// 单词规律

package Leetcode;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

class Solution_290_1 {
    public boolean wordPattern(String pattern, String s) {
        Map<Character, String> map = new HashMap<>();
        String[] words = s.split("\\s");

        if (words.length != pattern.length())
            return false;

        // 一次遍历，如果没有键则插入键值，如果存在键则比较值。
        for (int i = 0; i < pattern.length(); i++) {
            if (map.containsKey(pattern.charAt(i)) == false)
                map.put(pattern.charAt(i), words[i]);
            else {
                if (map.get(pattern.charAt(i)).equals(words[i]) == false)
                    return false;
            }
        }

        // 存在多个键映射同一值的情况，需要比较种类数量。
        Set<String> set = new HashSet<>();
        for (int i = 0; i < words.length; i++) {
            if (!set.contains(words[i]))
                set.add(words[i]);
        }

        if (map.size() != set.size())
            return false;

        return true;
    }
}

class Solution_290_2 {
    public boolean wordPattern(String pattern, String str) {
        String[] words = str.split(" ");
        // 字符和单词是互相映射，数量必须相等
        if (words.length != pattern.length()) {
            return false;
        }
        Map<Object, Integer> map = new HashMap<>();
        for (Integer i = 0; i < words.length; i++) {
            /*
             * 如果key不存在，插入成功，返回null；如果key存在，返回之前对应的value。
             * 
             * 以pattern = "abba", str = "dog cat cat dog"为例，
             * 第1次：map.put('a',0)返回null，map.put("dog",0)返回null，两者相等；
             * 第2次：map.put('b',1)返回null，map.put("cat",1)返回null，两者相等；
             * 第3次：map.put('b',2)返回1，map.put("cat",2)返回1，两者相等；
             * 第4次：map.put('a',3)返回0，map.put("dog",3)返回0，两者相等，
             * 结果为 true。
             * 
             * 以pattern = "abba", str = "dog cat cat fish"为例，
             * 第1次：map.put('a',0)返回null，map.put("dog",0)返回null，两者相等；
             * 第2次：map.put('b',1)返回null，map.put("cat",1)返回null，两者相等；
             * 第3次：map.put('b',2)返回1，map.put("cat",2)返回1，两者相等；
             * 第4次：map.put('a',3)返回0，map.put("fish",3)返回null，两者不相等，
             * 结果为 false。
             */
            if (map.put(pattern.charAt(i), i) != map.put(words[i], i)) {
                return false;
            }
        }
        return true;
    }
}